package org.xi.sims.service.impl;

import cn.hutool.core.bean.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.xi.sims.base.service.impl.IBaseServiceImpl;
import org.xi.sims.config.exception.CloudException;
import org.xi.sims.pojo.entity.Grade;
import org.xi.sims.pojo.form.GradeForm;
import org.xi.sims.pojo.form.SearchGradeForm;
import org.xi.sims.pojo.vo.GradeVO;
import org.xi.sims.pojo.vo.SelectVO;
import org.xi.sims.pojo.vo.StudentVO;
import org.xi.sims.repository.GradeRepository;
import org.xi.sims.service.CourseService;
import org.xi.sims.service.GradeService;
import org.xi.sims.service.StudentService;
import org.xi.sims.service.TeacherService;
import org.xi.sims.util.XinUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author ：xi
 * @time ：Created in 19:10
 * @description：
 */
@Service
public class GradeServiceImpl extends IBaseServiceImpl<Grade, GradeRepository> implements GradeService {

    @Autowired
    @Lazy
    private TeacherService teacherService;
    @Autowired
    @Lazy
    private StudentService studentService;
    @Autowired
    @Lazy
    private CourseService courseService;


    @Override
    public List<SelectVO> select() {
        return new ArrayList<SelectVO>() {{
            repository.findAll().forEach( one -> {
                this.add(SelectVO.builder().label(one.getName()).value(one.getId()).build());
            });
        }};
    }
    @Override
    public void deleteGrade(Integer id) {
        List<StudentVO> students = studentService.findVosByGradeId(id);
        if (XinUtil.noNull(students)) {
            throw new CloudException("该班级存在学生，请勿删除!");
        }
        repository.deleteById(id);
    }

    @Override
    public GradeVO saveOrUpdate(GradeForm form) {
        Grade grade = repository.findByNumber(form.getNumber());
        if (XinUtil.isNull(form.getId())) {
            if (XinUtil.noNull(grade)) {
                throw new CloudException("班级号：" + form.getNumber() + " 已存在!");
            }
            grade = BeanUtil.copyProperties(form, Grade.class);
            return vo(repository.save(grade));
        }
        if (XinUtil.noNull(grade)) {
            if (!Objects.equals(grade.getId(), form.getId())) {
                throw new CloudException("班级号：" + form.getNumber() + " 已存在!");
            }
            BeanUtil.copyProperties(form, grade);
        } else {
            grade = BeanUtil.copyProperties(form, Grade.class);
        }
        return vo(repository.save(grade));
    }

    @Override
    public GradeVO editNotice(Integer id, String notice) {
        Grade grade = findById(id);
        grade.setNotice(notice);
        return vo(save(grade));
    }

    @Override
    public List<GradeVO> findVOByTeacherId(Integer teacherId) {
        return vos(repository.findByTeacherId(teacherId));
    }

    @Override
    public String findGradeNameById(Integer id) {
        Grade grade = findById(id);
        if (XinUtil.isNull(grade)) {
            return "";
        }
        return grade.getName();
    }

    @Override
    public GradeVO vo(Grade grade) {
        GradeVO vo = BeanUtil.copyProperties(grade, GradeVO.class);
        vo.setTeacher(teacherService.findVoById(vo.getTeacherId()));
        vo.setStudents(studentService.findVosByGradeId(grade.getId()));
        vo.setCourses(courseService.findVosByGradeId(grade.getId()));
        return vo;
    }

    @Override
    public GradeVO findVoById(Integer id) {
        return vo(findById(id));
    }

    @Override
    public List<GradeVO> vos(List<Grade> grades) {
        return new ArrayList<GradeVO>() {{
            grades.forEach(grade -> {
                this.add(vo(grade));
            });
        }};
    }

    @Override
    public List<GradeVO> query(SearchGradeForm form) {
        Grade grade = Grade.builder().build();
        BeanUtil.copyProperties(form, grade);
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("number" ,ExampleMatcher.GenericPropertyMatchers.contains());
        Example<Grade> example = Example.of(grade, matcher);
        return vos(repository.findAll(example));
    }
}
